/**
 * 
 */
package labeling;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.util.List;

import javax.swing.BoxLayout;
import javax.swing.JPanel;

import com.alee.laf.StyleConstants;
import com.alee.laf.WebLookAndFeel;
import com.alee.laf.button.WebButton;
import com.alee.laf.label.WebLabel;
import com.alee.laf.panel.WebPanel;
import com.alee.laf.rootpane.WebFrame;
import com.alee.laf.scroll.WebScrollPane;
import com.alee.laf.text.WebTextArea;


/**
 * @author Jamada
 */
public class StatusUpdateLabelerDemo {
	private static final String LEXICON_FILE = "E:/fb_status_updates/NRC_Lexicon";
	private static final Dimension TEXT_AREA_PREF = new Dimension(150, 150);
	private static final Dimension TEXT_AREA_MAX = new Dimension (700, 100); 
    private static final Dimension FRAME_DIM = new Dimension(1300, 600);
    private static final String DEMO_FILE_NAME_TOKEN = "demo_input_token";
    private static final String DEMO_FILE_NAME_SPELL = "demo_input_spell";
    private static final String DEMO_FILE_NAME_NOT = "demo_input_not";
    private static final int NUM_SENTIMENTS = 10;
	private WebFrame frame;
	private WebTextArea inputArea;
	private WebTextArea tokenArea;
	private WebTextArea spellCheckArea;
	private WebTextArea notArea;
	private final String[] sentiments = {"Positive", "Negative", "Anger", "Anticipation", "Disgust", "Fear", "Joy", "Sadness", "Surprise", "Trust"};
	private final WebLabel[] tokenResults = new WebLabel[NUM_SENTIMENTS];
	private final WebLabel[] spellCheckResults = new WebLabel[NUM_SENTIMENTS];
	private final WebLabel[] notResults = new WebLabel[NUM_SENTIMENTS];
	private StatusUpdateLabeler tokenUpdateLabeler;
	private StatusUpdateLabeler spellUpdateLabeler;
	private StatusUpdateLabeler notUpdateLabeler;
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		new StatusUpdateLabelerDemo().start();
	}
	
	public StatusUpdateLabelerDemo() {
		this.frame = new WebFrame("Sentiment Labeler Demo");
		initializeWebLabels();
	}
	
	private void initializeWebLabels() {
		for (int i = 0; i < this.tokenResults.length; i++) {
			this.tokenResults[i] = new WebLabel();
			this.spellCheckResults[i] = new WebLabel();
			this.notResults[i] = new WebLabel();
		}
	}
	
	public void start() {
    	boolean decorateFrames = WebLookAndFeel.isDecorateFrames ();
        WebLookAndFeel.setDecorateFrames(true);
        this.frame.setIconImages(WebLookAndFeel.getImages());
        this.frame.setDefaultCloseOperation(WebFrame.EXIT_ON_CLOSE);
        this.frame.setPreferredSize(FRAME_DIM); 
        this.frame.add(buildDemoPanel());
        this.frame.pack();
        this.frame.setLocationRelativeTo(null);
        this.frame.setVisible(true);
        WebLookAndFeel.setDecorateFrames ( decorateFrames );  
	}
	
	public JPanel buildDemoPanel() {
		JPanel masterPanel = new JPanel();
		masterPanel.setLayout(new BoxLayout(masterPanel, BoxLayout.PAGE_AXIS));
    	masterPanel.setBackground(Color.white);
    	
    	//Labels
        WebLabel inputLabel = new WebLabel("Input for Sentiment Analysis");

        //inputLabel.setBackground(Color.white);
        this.inputArea = new WebTextArea ();
        this.inputArea.setText("I don't know half of you half as well as I should like; and I like less than half of you half as well as you deserve.");
        this.inputArea.setLineWrap ( true );
        this.inputArea.setWrapStyleWord ( true );

        WebScrollPane inputScroll = new WebScrollPane ( this.inputArea );
        inputScroll.setPreferredSize(TEXT_AREA_PREF);
        inputScroll.setMaximumSize (TEXT_AREA_MAX);
    	
        //Opacity
        inputLabel.setOpaque(false);
        
        //Alignment
        inputLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
        this.inputArea.setAlignmentX(Component.CENTER_ALIGNMENT);
        
        //Final construction
        masterPanel.add(inputLabel);
        masterPanel.add(inputScroll);
        masterPanel.add(getProcessButton());
        masterPanel.add(outputPanel());
    	
		return masterPanel;
	}
	
	private WebButton getProcessButton() {
        //Low Color Button
        final WebButton processButton = new WebButton("Analyze Sentiment");
		processButton.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				writeInputToFile(DEMO_FILE_NAME_TOKEN);
				writeInputToFile(DEMO_FILE_NAME_SPELL);
				writeInputToFile(DEMO_FILE_NAME_NOT);
				tokenUpdateLabeler = new StatusUpdateLabeler(LEXICON_FILE, false, false);
				spellUpdateLabeler = new StatusUpdateLabeler(LEXICON_FILE, true, false);
				notUpdateLabeler = new StatusUpdateLabeler(LEXICON_FILE, true, true);
				tokenUpdateLabeler.labelUpdatesIntoCSV(DEMO_FILE_NAME_TOKEN);
				spellUpdateLabeler.labelUpdatesIntoCSV(DEMO_FILE_NAME_SPELL);
				notUpdateLabeler.labelUpdatesIntoCSV(DEMO_FILE_NAME_NOT);
				
				List<String> tokens = tokenUpdateLabeler.getFinalTokens();
				final StringBuilder sb = new StringBuilder();
				for (int i = 0; i < tokens.size(); i++) {
					sb.append(tokens.get(i));
					sb.append(" ");
				}
				tokenArea.setText(sb.toString());
				
				tokens = spellUpdateLabeler.getFinalTokens();
				sb.setLength(0);
				for (int i = 0; i < tokens.size(); i++) {
					sb.append(tokens.get(i));
					sb.append(" ");
				}
				spellCheckArea.setText(sb.toString());
				
				tokens = notUpdateLabeler.getFinalTokens();
				sb.setLength(0);
				for (int i = 0; i < tokens.size(); i++) {
					if (tokens.get(i).equals("not")) {
						sb.append(tokens.get(i).toUpperCase());
					} else {
						sb.append(tokens.get(i));
					}
					sb.append(" ");
				}
				notArea.setText(sb.toString());
				
				//Update results
				updateSentimentLabels();
			}
		});  
		processButton.setAlignmentX(Component.CENTER_ALIGNMENT);
		return processButton;
	}
	
	private void updateSentimentLabels() {
		final int[] tokenSent = tokenUpdateLabeler.getFinalSentimentScores();
		final int[] spellSent = spellUpdateLabeler.getFinalSentimentScores();
		final int[] notSent = notUpdateLabeler.getFinalSentimentScores();
		for (int i = 0; i < tokenSent.length; i++) {
			this.tokenResults[i].setText("" + tokenSent[i]);
			this.spellCheckResults[i].setText("" + spellSent[i]);
			this.notResults[i].setText("" + notSent[i]);
		}
	}
	
	private void writeInputToFile(final String fileName) {
		try {
			BufferedWriter bWriter = new BufferedWriter(new FileWriter(fileName + ".csv"));
			this.inputArea.getText();
			String result = "hi, there, how\nare, you, " + this.inputArea.getText();
			System.out.println(this.inputArea.getText());
			bWriter.write(result);
			bWriter.close();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}
	
	private WebTextArea setupTextArea() {
		WebTextArea resultArea = new WebTextArea();
        resultArea.setLineWrap ( true );
        resultArea.setWrapStyleWord ( true );
        resultArea.setAlignmentX(Component.CENTER_ALIGNMENT);
		return resultArea;
	}
	
	private WebScrollPane addTextAreaScroll(final WebTextArea textArea) {
        WebScrollPane areaScroll = new WebScrollPane ( textArea );
        areaScroll.setPreferredSize(TEXT_AREA_PREF);
        areaScroll.setMaximumSize (TEXT_AREA_MAX);
        return areaScroll;
	}
	private JPanel outputPanel() {
        final WebPanel result = new WebPanel();
        result.setUndecorated ( false );
        result.setMargin ( 20 );
        result.setRound ( StyleConstants.largeRound );
        //result.getWebUI().setPaintBackground(false);
        result.setLayout(new BoxLayout(result, BoxLayout.PAGE_AXIS));
        
        //Text Areas
        this.tokenArea = setupTextArea();
        this.spellCheckArea = setupTextArea();
        this.notArea = setupTextArea();
        
        WebScrollPane tokenScroll = addTextAreaScroll(this.tokenArea);
        WebScrollPane spellCheckScroll = addTextAreaScroll(this.spellCheckArea);
        WebScrollPane notScroll = addTextAreaScroll(this.notArea);
        
        //Labels
        WebLabel resultLabel = new WebLabel("Results");
        WebLabel tokenLabel = new WebLabel("Tokenized");
        WebLabel spellLabel = new WebLabel("Spell Checked");
        WebLabel notLabel = new WebLabel("Negation");
        
        //Opacity
        resultLabel.setOpaque(false);
        tokenLabel.setOpaque(false);
        spellLabel.setOpaque(false);
        notLabel.setOpaque(false);
        
        //Alignment
        resultLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
        tokenLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
        spellLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
        notLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
        
        //Final Construction
        result.add(tokenLabel);
        result.add(tokenScroll);
        result.add(spellLabel);
        result.add(spellCheckScroll);
        result.add(notLabel);
        result.add(notScroll);
        result.add(resultsGrid());
        
        return result;
	}
	
	private JPanel resultsGrid() {
        JPanel gridPanel = new JPanel();
        gridPanel.setOpaque(false);
        final int col = 11;
        final int row = 4;
        GridLayout grid = new GridLayout(row, col);
        //grid.setHgap(5);
        grid.setVgap(10);
        gridPanel.setLayout(grid);
        
        WebLabel empty = new WebLabel("");      
        gridPanel.add(empty);
        for (int i = 0; i < col - 1; i++) {
        	gridPanel.add(new WebLabel(sentiments[i]));
        }
        WebLabel tokenLabel = new WebLabel("Tokenized Only");
        gridPanel.add(tokenLabel);
        for (int i = 0; i < col - 1; i++) {
        	gridPanel.add(this.tokenResults[i]);
        }
        WebLabel spellLabel = new WebLabel("Spell Checked");
        gridPanel.add(spellLabel);
        for (int i = 0; i < col - 1; i++) {
        	gridPanel.add(this.spellCheckResults[i]);
        }
        WebLabel notLabel = new WebLabel("Negation");
        gridPanel.add(notLabel);
        for (int i = 0; i < col - 1; i++) {
        	gridPanel.add(this.notResults[i]);
        }
        
        //Opacity
        empty.setOpaque(false);
        tokenLabel.setOpaque(false);
        spellLabel.setOpaque(false);
        notLabel.setOpaque(false);
        
        return gridPanel;
	}
}
